﻿using System;
using System.Threading.Tasks;
using System.Transactions;
using Elsa.Services.Models;
using HengTong.Model;
using HengTong.Model.Db.Hr.Attendance;
using HengTong.Model.Request;
using TiaoTaoHelper.Wtm.Interfaces;
using TiaoTaoHelper.Wtm.Models;
using TiaoTaoHelper.Wtm.Workflow;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.WorkFlow;

namespace HengTong.ViewModel.Daily.SysDailyLeaveRequestBillVms;

public partial class SysDailyLeaveRequestBillVm
{
    [WorkflowOperation("驳回", "将单据状态设置为草稿", "请假出差")]
    public async Task Reject(ActivityExecutionContext context)
    {
        Entity.BillStatus = BillStatus.草稿;
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        DC.UpdateProperty(Entity, x => x.BillStatus);
        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("取消", "将流程状态设置为取消", "请假出差")]
    public async Task Cancel(ActivityExecutionContext context)
    {
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        if (Entity is IBill bill)
        {
            bill.WorkflowStatus = WorkflowStatus.已取消;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);
        }

        await DC.SaveChangesAsync();
    }


    // 统一改为调用人工排班批处理, 使用 ShiftType=请假
    [WorkflowOperation("请假处理", "将流程状态设置为已完成并调用人工排班接口", "请假出差")]
    public async Task Complete(ActivityExecutionContext context)
    {
        string currentUser = "workflow";
        if (context.Input is WtmApproveInput input)
            currentUser = input.CurrentUser?.ITCode ?? "workflow";

        using var scope = new TransactionScope(
            TransactionScopeOption.Required,
            new TransactionOptions
                { IsolationLevel = IsolationLevel.ReadCommitted, Timeout = TimeSpan.FromMinutes(10) },
            TransactionScopeAsyncFlowOption.Enabled);

        try
        {
            if (Entity.PersonId == null || Entity.StartTime == null || Entity.EndTime == null)
            {
                MSD.AddModelError(" ", "单据数据不完整");
                return;
            }

            // 判断是否需要处理考勤记录
            bool shouldProcessAttendance = false;
            ShiftAction shiftAction = ShiftAction.请假;

            if (Entity.LeaveType == LeaveType.请假)
            {
                shouldProcessAttendance = true;
                shiftAction = ShiftAction.请假;
            }
            else if (Entity.LeaveType == LeaveType.出差 && Entity.AffectsAttendance == true)
            {
                shouldProcessAttendance = true;
                shiftAction = ShiftAction.出差;
            }

            if (shouldProcessAttendance)
            {
                var start = Entity.StartTime.Value.Date;
                var endExclusive = Entity.EndTime.Value.Date;

                var req = new AddAttendanceRecordsRequest
                {
                    PersonIds = new[] { Entity.PersonId.Value },
                    ShiftType = shiftAction,
                    DateRange = new DateRange(start, endExclusive),
                    AutoCalculateFuture = false,
                    AttendanceShiftGroupId = null
                };

                var vm = Wtm.CreateVM<Hr.SysAttendanceRecordVms.SysAttendanceRecordBatchVm>();
                var ok = await vm.DoBatchAddAsync(req, ScheduleTypeEnum.流程排班, Entity.ID);
                if (!ok)
                {
                    MSD.AddModelError(" ", "人工排班处理失败");
                    return;
                }
            }

            if (Entity is IBasePoco poco)
            {
                poco.UpdateTime = DateTime.Now;
                poco.UpdateBy = currentUser;
                DC.UpdateProperty(Entity, x => x.UpdateTime);
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }

            if (Entity is IBill bill)
            {
                bill.WorkflowStatus = WorkflowStatus.已完成;
                DC.UpdateProperty(Entity, x => x.WorkflowStatus);
            }

            await DC.SaveChangesAsync();
            scope.Complete();
        }
        catch (Exception e)
        {
            MSD.AddModelError(" ", $"完成请假申请失败: {e.Message}");
        }
    }


    /*[WorkflowOperation("请假处理", "将流程状态设置为已完成并处理考勤记录", "请假出差")]
    public async Task Complete(ActivityExecutionContext context)
    {
        string currentUser = "workflow";
        if (context.Input is WtmApproveInput input)
        {
            currentUser = input.CurrentUser?.ITCode ?? "workflow";
        }

        using var transactionScope = new TransactionScope(
            TransactionScopeOption.Required,
            new TransactionOptions
            {
                IsolationLevel = IsolationLevel.ReadCommitted,
                Timeout = TimeSpan.FromMinutes(10)
            },
            TransactionScopeAsyncFlowOption.Enabled);

        try
        {
            // 处理考勤记录逻辑
            var startDate = Entity.StartTime.Value;
            var endDate = Entity.EndTime.Value;
            var leaveStartDate = DateOnly.FromDateTime(startDate);
            var leaveEndDate = DateOnly.FromDateTime(endDate);

            // 查询请假期间已有的考勤记录
            var existingRecords = await DC.Set<SysAttendanceRecord>()
                .Where(x => x.PersonId == Entity.PersonId.Value
                            && x.ShiftDate >= leaveStartDate
                            && x.ShiftDate <= leaveEndDate)
                .ToListAsync();

            // 处理请假期间的考勤记录
            var recordsToUpdate = new List<Guid>();
            var recordsToAdd = new List<SysAttendanceRecord>();

            // 循环请假期间的每一天
            for (var date = leaveStartDate; date <= leaveEndDate; date = date.AddDays(1))
            {
                var existingRecord = existingRecords.FirstOrDefault(x => x.ShiftDate == date);

                if (existingRecord != null)
                {
                    // 如果记录状态为正常，则更新为请假
                    if (existingRecord.Status == ShiftStatusEnum.正常 &&
                        existingRecord.AttendanceResult == AttendanceResultEnum.未计算)
                    {
                        recordsToUpdate.Add(existingRecord.ID);
                    }
                    // 如果状态为非正常，需要新增一条正常的请假记录
                    else if (existingRecord.Status != ShiftStatusEnum.正常 &&
                             existingRecord.AttendanceResult == AttendanceResultEnum.未计算)
                    {
                        var newLeaveRecord = new SysAttendanceRecord
                        {
                            ID = Guid.NewGuid(),
                            PersonId = Entity.PersonId.Value,
                            ShiftDate = date,
                            AttendanceShiftGroupId = existingRecord.AttendanceShiftGroupId,
                            ShiftType = ShiftTypeEnum.请假,
                            ScheduleType = ScheduleTypeEnum.人工排班,
                            Status = ShiftStatusEnum.正常,
                            AttendanceResult = AttendanceResultEnum.未计算,
                            IsAbnormal = false
                        };
                        recordsToAdd.Add(newLeaveRecord);
                    }
                }
            }

            // 批量更新状态为正常的记录
            if (recordsToUpdate.Count > 0)
            {
                await DC.Set<SysAttendanceRecord>()
                    .Where(x => recordsToUpdate.Contains(x.ID))
                    .ExecuteUpdateAsync(x => x.SetProperty(r => r.ShiftType, ShiftTypeEnum.请假));
            }

            // 批量新增状态为非正常的请假记录
            if (recordsToAdd.Count > 0)
            {
                await DC.Set<SysAttendanceRecord>().AddRangeAsync(recordsToAdd);
                await DC.SaveChangesAsync();
            }

            // 更新单据基础信息
            if (Entity is IBasePoco poco)
            {
                poco.UpdateTime = DateTime.Now;
                DC.UpdateProperty(Entity, x => x.UpdateTime);
                poco.UpdateBy = currentUser;
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }

            // 更新工作流状态
            if (Entity is IBill bill)
            {
                bill.WorkflowStatus = WorkflowStatus.已完成;
                DC.UpdateProperty(Entity, x => x.WorkflowStatus);
            }

            await DC.SaveChangesAsync();
            transactionScope.Complete();
        }
        catch (Exception e)
        {
            MSD.AddModelError(" ", $"完成请假申请失败: {e.Message}");
        }
    }*/
}